#include "EMS_pwm_drv.h"

#define EMS_TIMER_1k_PERIOD		(1000)

#define EMS_TIMER_10k_PERIOD		(50*2)
#define EMS_TIMER_10k_DUTY		(EMS_TIMER_10k_PERIOD*6/10)

static TIM_TimeBaseInitType TIM_TimeBaseStructure;
static OCInitType TIM_OCInitStructure;
static uint16_t CCR1_Val       = 333;
static uint16_t CCR2_Val       = 249;
static uint16_t CCR3_Val       = 166;
static uint16_t CCR4_Val       = 83;
static uint16_t PrescalerValue = 0;

static int cur_period_timer_cnt = 0;
static int cur_duty_timer_cnt = 0;


/**
 * @brief  Inserts a delay time.
 * @param count specifies the delay time length.
 */
__inline static void my_delay(uint32_t count)
{
    for (; count > 0; count--)
        ;
}

/**
 * @brief  Configures the different system clocks.
 */
void ems_rcc_cfg(void)
{
    /* TIM3 clock enable */
    // RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM3, ENABLE);
    // timer 2
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM2, ENABLE);
    // timer 5
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM5, ENABLE);

    /* GPIOA and GPIOB clock enable */
    RCC_EnableAPB2PeriphClk(
        RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_GPIOB | RCC_APB2_PERIPH_GPIOC | RCC_APB2_PERIPH_AFIO, ENABLE);
}

/**
 * @brief  Configure the TIM3 Ouput Channels.
 */
void ems_gpio_cfg(void)
{
    GPIO_InitType GPIO_InitStructure;

    GPIO_InitStruct(&GPIO_InitStructure);
    /* GPIOA Configuration:TIM3 Channel1, 2, 3 and 4 as alternate function push-pull */
    // // PA1 ----[TIM2_CH2 ---AF2]  JE3 pa1
    // GPIO_InitStructure.Pin        = GPIO_PIN_1;
    // GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    // GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
    // GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_TIM2;
    // GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
    
    // JY1 --PA15--[TIM2_CH1 ---AF5] ------
    GPIO_InitStructure.Pin        = GPIO_PIN_15;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF5_TIM2;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);


    // PA2 ----[TIM5_CH3 ---AF6]
    GPIO_InitStructure.Pin        = GPIO_PIN_2;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Current = GPIO_DC_4mA;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF6_TIM5;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
}

static void ems_gpi_deinit(void)
{
  gpio_output_cfg(GPIOA, GPIO_PIN_15);
	set_pin_low(GPIOA, GPIO_PIN_15);

  gpio_output_cfg(GPIOA, GPIO_PIN_2);
	set_pin_low(GPIOA, GPIO_PIN_2);
}

//----------ems 通道1 关闭 / 开启
void ems_playlod1_stop(void)
{
    // TIM2->CCDAT2 = 0; //TIM_TimeBaseStructure.Period   TIM_OCInitStructure.Pulse  EMS_TIMER_10k_PERIOD
    // TIM5->CCDAT3 = 0;

    TIM_Enable(TIM2, DISABLE);
    TIM_Enable(TIM5, DISABLE);
    ems_gpi_deinit();
}

void ems_playlod1_restar(void)
{
    // /* TIM2 enable counter */
    // TIM2->CCDAT2 = TIM_OCInitStructure.Pulse;
    // TIM5->CCDAT3 = TIM_OCInitStructure.Pulse;
}

void ems_playlod1_restar_with_duty(int duty)
{
  /* TIM2 enable counter */
	TIM2->CCDAT1 = TIM_TimeBaseStructure.Period *(duty)/100;
	TIM5->CCDAT3 = TIM_TimeBaseStructure.Period *(duty)/100;
}


/***************************
 * 
 * 
 * 
 *************************/

void ems_freq_select_1hz(void)
{
    ems_output_disable();
	  TIM_Enable(TIM2, DISABLE);
		TIM_Enable(TIM5, DISABLE);
    ems_gpi_deinit();


    ems_gpio_cfg();
  /* Compute the prescaler value */
    PrescalerValue = 40000; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    // PrescalerValue =1 (uint16_t)(SystemCoreClock / 10800000) - 1;; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);    
    TIM_TimeBaseStructure.Period    = EMS_TIMER_10k_PERIOD;
    TIM_TimeBaseStructure.Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    //-------------timer 2 ch1    
    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = EMS_TIMER_10k_DUTY; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;
    // CH1
    TIM_InitOc1(TIM2, &TIM_OCInitStructure);
    TIM_ConfigOc1Preload(TIM2, TIM_OC_PRE_LOAD_ENABLE);
    TIM_Enable(TIM2, ENABLE);
    //---------------timer 5 ch2

    TIM_InitTimeBase(TIM5, &TIM_TimeBaseStructure);

    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = EMS_TIMER_10k_DUTY; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;
    // CH3
    TIM_InitOc3(TIM5, &TIM_OCInitStructure);
    TIM_ConfigOc3Preload(TIM5, TIM_OC_PRE_LOAD_ENABLE);
		my_delay(11000000/2);
    TIM_Enable(TIM5, ENABLE);
    ems_output_enable();
}


/***************************
 * 
 * 
 * 
 *************************/
void ems_freq_select_100hz(EMS_DUTY_LEVEL_e duty_level)
{
  int cur_duty;

  switch(duty_level){
    case EMS_LITTLE_DUTY:{
      cur_duty = EMS_100HZ_LITTLE_DUTY;
      break;
    }
    case EMS_MIDDLE_DUTY:{
      cur_duty = EMS_100HZ_MIDDLE_DUTY;
      break;
    }
    case EMS_LARGE_DUTY:{
      cur_duty = EMS_100HZ_LARGE_DUTY;
      break;
    }
    default:{
      cur_duty = EMS_100HZ_LITTLE_DUTY;
    }
  }


    ems_output_disable();
	  TIM_Enable(TIM2, DISABLE);
		TIM_Enable(TIM5, DISABLE);

    ems_gpi_deinit();

    ems_gpio_cfg();

  /* Compute the prescaler value */
    PrescalerValue = 64 -1; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    // PrescalerValue =1 (uint16_t)(SystemCoreClock / 10800000) - 1;; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);    
    TIM_TimeBaseStructure.Period    = EMS_TIMER_1k_PERIOD*10 - 1;
    TIM_TimeBaseStructure.Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    //-------------timer 2 ch1    
    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc1(TIM2, &TIM_OCInitStructure);
    TIM_ConfigOc1Preload(TIM2, TIM_OC_PRE_LOAD_ENABLE);
    TIM_Enable(TIM2, ENABLE);
    //---------------timer 5 ch2

    TIM_InitTimeBase(TIM5, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc3(TIM5, &TIM_OCInitStructure);
    TIM_ConfigOc3Preload(TIM5, TIM_OC_PRE_LOAD_ENABLE);
		// my_delay(500*20);
    my_delay(3500*20); // 20241008 修改
    TIM_Enable(TIM5, ENABLE);
    ems_output_enable();
}


/***************************
 * 
 * 
 * 
 *************************/
void ems_freq_select_500hz(EMS_DUTY_LEVEL_e duty_level)
{

  int cur_duty;

  switch(duty_level){
    case EMS_LITTLE_DUTY:{
      cur_duty = EMS_500HZ_LITTLE_DUTY;
      break;
    }
    case EMS_MIDDLE_DUTY:{
      cur_duty = EMS_500HZ_MIDDLE_DUTY;
      break;
    }
    case EMS_LARGE_DUTY:{
      cur_duty = EMS_500HZ_LARGE_DUTY;
      break;
    }
    default:{
      cur_duty = EMS_500HZ_LITTLE_DUTY;
    }
  }

    ems_output_disable();
	  TIM_Enable(TIM2, DISABLE);
		TIM_Enable(TIM5, DISABLE);

    ems_gpi_deinit();

    ems_gpio_cfg();

  /* Compute the prescaler value */
    PrescalerValue = 64 -1; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    // PrescalerValue =1 (uint16_t)(SystemCoreClock / 10800000) - 1;; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);    
    TIM_TimeBaseStructure.Period    = EMS_TIMER_1k_PERIOD*2 - 1;
    TIM_TimeBaseStructure.Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    //-------------timer 2 ch1    
    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc1(TIM2, &TIM_OCInitStructure);
    TIM_ConfigOc1Preload(TIM2, TIM_OC_PRE_LOAD_ENABLE);
    TIM_Enable(TIM2, ENABLE);
    //---------------timer 5 ch2

    TIM_InitTimeBase(TIM5, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc3(TIM5, &TIM_OCInitStructure);
    TIM_ConfigOc3Preload(TIM5, TIM_OC_PRE_LOAD_ENABLE);
		// my_delay(500*20);
    my_delay(700*20); // 20241008 修改
    TIM_Enable(TIM5, ENABLE);
    ems_output_enable();
}


/***************************
 * 
 * 
 * 
 *************************/
void ems_freq_select_1khz(EMS_DUTY_LEVEL_e duty_level)
{

  int cur_duty;

  switch(duty_level){
    case EMS_LITTLE_DUTY:{
      cur_duty = EMS_1KHZ_LITTLE_DUTY;
      break;
    }
    case EMS_MIDDLE_DUTY:{
      cur_duty = EMS_1KHZ_MIDDLE_DUTY;
      break;
    }
    case EMS_LARGE_DUTY:{
      cur_duty = EMS_1KHZ_LARGE_DUTY;
      break;
    }
    default:{
      cur_duty = EMS_1KHZ_LITTLE_DUTY;
    }
  }

    ems_output_disable();
	  TIM_Enable(TIM2, DISABLE);
		TIM_Enable(TIM5, DISABLE);

    ems_gpi_deinit();

    ems_gpio_cfg();

  /* Compute the prescaler value */
    PrescalerValue = 64 -1; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    // PrescalerValue =1 (uint16_t)(SystemCoreClock / 10800000) - 1;; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);    
    TIM_TimeBaseStructure.Period    = EMS_TIMER_1k_PERIOD - 1;
    TIM_TimeBaseStructure.Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    //-------------timer 2 ch1    
    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc1(TIM2, &TIM_OCInitStructure);
    TIM_ConfigOc1Preload(TIM2, TIM_OC_PRE_LOAD_ENABLE);
    TIM_Enable(TIM2, ENABLE);
    //---------------timer 5 ch2

    TIM_InitTimeBase(TIM5, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc3(TIM5, &TIM_OCInitStructure);
    TIM_ConfigOc3Preload(TIM5, TIM_OC_PRE_LOAD_ENABLE);
		my_delay(500*15);
    TIM_Enable(TIM5, ENABLE);
    ems_output_enable();
}

/***************************
 * 
 * 
 * 
 *************************/
void ems_freq_select_2khz(EMS_DUTY_LEVEL_e duty_level)
{

  int cur_duty;

  switch(duty_level){
    case EMS_LITTLE_DUTY:{
      cur_duty = EMS_2KHZ_LITTLE_DUTY;
      break;
    }
    case EMS_MIDDLE_DUTY:{
      cur_duty = EMS_2KHZ_MIDDLE_DUTY;
      break;
    }
    case EMS_LARGE_DUTY:{
      cur_duty = EMS_2KHZ_LARGE_DUTY;
      break;
    }
    default:{
      cur_duty = EMS_2KHZ_LITTLE_DUTY;
    }
  }


    ems_output_disable();
	  TIM_Enable(TIM2, DISABLE);
		TIM_Enable(TIM5, DISABLE);

    ems_gpi_deinit();

    ems_gpio_cfg();
  /* Compute the prescaler value */
    PrescalerValue = 64 -1; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    // PrescalerValue =1 (uint16_t)(SystemCoreClock / 10800000) - 1;; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);    
    TIM_TimeBaseStructure.Period    = EMS_TIMER_1k_PERIOD/2 - 1;
    TIM_TimeBaseStructure.Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    //-------------timer 2 ch1    
    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc1(TIM2, &TIM_OCInitStructure);
    TIM_ConfigOc1Preload(TIM2, TIM_OC_PRE_LOAD_ENABLE);
    TIM_Enable(TIM2, ENABLE);
    //---------------timer 5 ch2

    TIM_InitTimeBase(TIM5, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc3(TIM5, &TIM_OCInitStructure);
    TIM_ConfigOc3Preload(TIM5, TIM_OC_PRE_LOAD_ENABLE);
		my_delay(500*6);
    TIM_Enable(TIM5, ENABLE);
    ems_output_enable();
}




void ems_freq_select_3khz(EMS_DUTY_LEVEL_e duty_level)
{

  int cur_duty;

  switch(duty_level){
    case EMS_LITTLE_DUTY:{
      cur_duty = EMS_3KHZ_LITTLE_DUTY;
      break;
    }
    case EMS_MIDDLE_DUTY:{
      cur_duty = EMS_3KHZ_MIDDLE_DUTY;
      break;
    }
    case EMS_LARGE_DUTY:{
      cur_duty = EMS_3KHZ_LARGE_DUTY;
      break;
    }
    default:{
      cur_duty = EMS_3KHZ_LITTLE_DUTY;
    }
  }

  ems_output_disable();
  TIM_Enable(TIM2, DISABLE);
  TIM_Enable(TIM5, DISABLE);

    ems_gpi_deinit();

    ems_gpio_cfg();
  /* Compute the prescaler value */
    PrescalerValue = 64 -1 ; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    // PrescalerValue =1 (uint16_t)(SystemCoreClock / 10800000) - 1;; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);    
    TIM_TimeBaseStructure.Period    = EMS_TIMER_1k_PERIOD/3 - 1;
    TIM_TimeBaseStructure.Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    //-------------timer 2 ch1    
    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc1(TIM2, &TIM_OCInitStructure);
    TIM_ConfigOc1Preload(TIM2, TIM_OC_PRE_LOAD_ENABLE);
    TIM_Enable(TIM2, ENABLE);
    //---------------timer 5 ch2

    TIM_InitTimeBase(TIM5, &TIM_TimeBaseStructure);

    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc3(TIM5, &TIM_OCInitStructure);
    TIM_ConfigOc3Preload(TIM5, TIM_OC_PRE_LOAD_ENABLE);
		my_delay(1200*2);
    TIM_Enable(TIM5, ENABLE);
    cur_period_timer_cnt = TIM_TimeBaseStructure.Period;
    cur_duty_timer_cnt = TIM_OCInitStructure.Pulse;
    ems_output_enable();
}


/***************************
 * 
 * 
 * 
 *************************/
void ems_freq_select_4khz(EMS_DUTY_LEVEL_e duty_level)
{
  int cur_duty;

  switch(duty_level){
    case EMS_LITTLE_DUTY:{
      cur_duty = EMS_4KHZ_LITTLE_DUTY;
      break;
    }
    case EMS_MIDDLE_DUTY:{
      cur_duty = EMS_4KHZ_MIDDLE_DUTY;
      break;
    }
    case EMS_LARGE_DUTY:{
      cur_duty = EMS_4KHZ_LARGE_DUTY;
      break;
    }
    default:{
      cur_duty = EMS_4KHZ_LITTLE_DUTY;
    }
  }

    ems_output_disable();
	  TIM_Enable(TIM2, DISABLE);
		TIM_Enable(TIM5, DISABLE);

    ems_gpi_deinit();

    ems_gpio_cfg();
  /* Compute the prescaler value */
    PrescalerValue = 64 - 1; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    // PrescalerValue =1 (uint16_t)(SystemCoreClock / 10800000) - 1;; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);    
    TIM_TimeBaseStructure.Period    = EMS_TIMER_1k_PERIOD/4 - 1;
    TIM_TimeBaseStructure.Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    //-------------timer 2 ch1    
    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc1(TIM2, &TIM_OCInitStructure);
    TIM_ConfigOc1Preload(TIM2, TIM_OC_PRE_LOAD_ENABLE);
    TIM_Enable(TIM2, ENABLE);
    //---------------timer 5 ch2

    TIM_InitTimeBase(TIM5, &TIM_TimeBaseStructure);

    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc3(TIM5, &TIM_OCInitStructure);
    TIM_ConfigOc3Preload(TIM5, TIM_OC_PRE_LOAD_ENABLE);
		my_delay(1000*2);
    TIM_Enable(TIM5, ENABLE);
    ems_output_enable();
}

/*******
 *  ems cfg 9khz
 * 
 * ****/
void ems_freq_select_9khz(EMS_DUTY_LEVEL_e duty_level)
{
  int cur_duty;

  switch(duty_level){
    case EMS_LITTLE_DUTY:{
      cur_duty = EMS_9KHZ_LITTLE_DUTY;
      break;
    }
    case EMS_MIDDLE_DUTY:{
      cur_duty = EMS_9KHZ_MIDDLE_DUTY;
      break;
    }
    case EMS_LARGE_DUTY:{
      cur_duty = EMS_9KHZ_LARGE_DUTY;
      break;
    }
    default:{
      cur_duty = EMS_9KHZ_LITTLE_DUTY;
    }
  }

  ems_output_disable();
  TIM_Enable(TIM2, DISABLE);
  TIM_Enable(TIM5, DISABLE);

    ems_gpi_deinit();

    ems_gpio_cfg();
  /* Compute the prescaler value */
    PrescalerValue = 64 -1 ; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    // PrescalerValue =1 (uint16_t)(SystemCoreClock / 10800000) - 1;; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);    
    TIM_TimeBaseStructure.Period    = EMS_TIMER_1k_PERIOD/9;
    TIM_TimeBaseStructure.Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    //-------------timer 2 ch1    
    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;
    // CH1
    TIM_InitOc1(TIM2, &TIM_OCInitStructure);
    TIM_ConfigOc1Preload(TIM2, TIM_OC_PRE_LOAD_ENABLE);
    TIM_Enable(TIM2, ENABLE);
    //---------------timer 5 ch2

    TIM_InitTimeBase(TIM5, &TIM_TimeBaseStructure);

    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc3(TIM5, &TIM_OCInitStructure);
    TIM_ConfigOc3Preload(TIM5, TIM_OC_PRE_LOAD_ENABLE);
		my_delay(900*9);
    TIM_Enable(TIM5, ENABLE);
    cur_period_timer_cnt = TIM_TimeBaseStructure.Period;
    cur_duty_timer_cnt = TIM_OCInitStructure.Pulse;
    ems_output_enable();
}


/*******
 *  ems cfg 10khz
 * 
 * ****/
void ems_freq_select_12khz(EMS_DUTY_LEVEL_e duty_level)
{

  int cur_duty;

  switch(duty_level){
    case EMS_LITTLE_DUTY:{
      cur_duty = EMS_12KHZ_LITTLE_DUTY;
      break;
    }
    case EMS_MIDDLE_DUTY:{
      cur_duty = EMS_12KHZ_MIDDLE_DUTY;
      break;
    }
    case EMS_LARGE_DUTY:{
      cur_duty = EMS_12KHZ_LARGE_DUTY;
      break;
    }
    default:{
      cur_duty = EMS_12KHZ_LITTLE_DUTY;
    }
  }

  ems_output_disable();
    TIM_Enable(TIM2, DISABLE);
  TIM_Enable(TIM5, DISABLE);

    ems_gpi_deinit();

    ems_gpio_cfg();
  /* Compute the prescaler value */
    PrescalerValue = 64 -1 ; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    // PrescalerValue =1 (uint16_t)(SystemCoreClock / 10800000) - 1;; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);    
    TIM_TimeBaseStructure.Period    = EMS_TIMER_1k_PERIOD/12;
    TIM_TimeBaseStructure.Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    //-------------timer 2 ch1    
    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;
    //------------- ch1 
    TIM_InitOc1(TIM2, &TIM_OCInitStructure);
    TIM_ConfigOc1Preload(TIM2, TIM_OC_PRE_LOAD_ENABLE);
    TIM_Enable(TIM2, ENABLE);

    //---------------timer 5 ch2
    TIM_InitTimeBase(TIM5, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc3(TIM5, &TIM_OCInitStructure);
    TIM_ConfigOc3Preload(TIM5, TIM_OC_PRE_LOAD_ENABLE);
		my_delay(900*11);
    TIM_Enable(TIM5, ENABLE);
    cur_period_timer_cnt = TIM_TimeBaseStructure.Period;
    cur_duty_timer_cnt = TIM_OCInitStructure.Pulse;
    ems_output_enable();
}

/*******
 *  ems cfg 15khz
 * 
 * ****/
void ems_freq_select_15khz(EMS_DUTY_LEVEL_e duty_level)
{
  int cur_duty;

  switch(duty_level){
    case EMS_LITTLE_DUTY:{
      cur_duty = EMS_15KHZ_LITTLE_DUTY;
      break;
    }
    case EMS_MIDDLE_DUTY:{
      cur_duty = EMS_15KHZ_MIDDLE_DUTY;
      break;
    }
    case EMS_LARGE_DUTY:{
      cur_duty = EMS_15KHZ_LARGE_DUTY;
      break;
    }
    default:{
      cur_duty = EMS_15KHZ_LITTLE_DUTY;
    }
  }


  ems_output_disable();
  TIM_Enable(TIM2, DISABLE);
  TIM_Enable(TIM5, DISABLE);


  ems_gpi_deinit();

  ems_gpio_cfg();
  /* Compute the prescaler value */
    PrescalerValue = 64 -1 ; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    // PrescalerValue =1 (uint16_t)(SystemCoreClock / 10800000) - 1;; //(uint16_t)(SystemCoreClock / 12000000) - 1;
    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);    
    TIM_TimeBaseStructure.Period    = EMS_TIMER_1k_PERIOD/15 - 1;
    TIM_TimeBaseStructure.Prescaler = PrescalerValue;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    //-------------timer 2 ch1    
    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);
    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc1(TIM2, &TIM_OCInitStructure);
    TIM_ConfigOc1Preload(TIM2, TIM_OC_PRE_LOAD_ENABLE);
    TIM_Enable(TIM2, ENABLE);
    //---------------timer 5 ch2

    TIM_InitTimeBase(TIM5, &TIM_TimeBaseStructure);

    /* PWM1 Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);    
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = TIM_TimeBaseStructure.Period *cur_duty /100; //CCR1_Val;
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc3(TIM5, &TIM_OCInitStructure);
    TIM_ConfigOc3Preload(TIM5, TIM_OC_PRE_LOAD_ENABLE);
		// my_delay(200 + 100);  //200

    my_delay(200 + 250);
    TIM_Enable(TIM5, ENABLE);
    cur_period_timer_cnt = TIM_TimeBaseStructure.Period;
    cur_duty_timer_cnt = TIM_OCInitStructure.Pulse;
    ems_output_enable();
}


/*******
 *  ems 频率20khz， 占空比25%
 * 
 * ****/

void my_ems_init(void)
{
  ems_rcc_cfg();
  // ems_gpio_cfg();
  ems_freq_select_3khz(EMS_DEFAULT_DUTY);
}
